package com.wlyuan.open.domain.source.dispatcher.conversion;

import com.wlyuan.core.exception.AssertUtils;
import com.wlyuan.core.exception.ValueError;
import com.wlyuan.open.domain.source.repository.cache.OpenBillCacheRepository;
import com.wlyuan.open.dto.OpenPaySyncDTO;
import com.wlyuan.open.utils.LongUtils;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import lombok.var;
import org.springframework.stereotype.Service;
import org.springframework.util.CollectionUtils;

import java.util.Optional;

/**
 * @author lijing
 * @description
 */
@RequiredArgsConstructor
@Service
@Slf4j
public class OpenDispatcherPayConversion implements OpenDispatcherConversion<OpenPaySyncDTO> {
    private final BaseOpenDispatcherConversion baseOpenDispatcherConversion;
    private final OpenBillCacheRepository openBillCacheRepository;
    private final OpenDispatcherBillConversion openDispatcherBillConversion;

    @Override
    public void convert(OpenPaySyncDTO source) {
        //租户
        convertTenant(source);
        //所属id
        convertBelongId(source);
        //用户
        convertUser(source);
        //上游
        upConvert(source);
        //下游
        downConvert(source);
        //运单
        transportConvert(source);
    }

    private void convertTenant(OpenPaySyncDTO source) {
        var tenant = source.getTenantId();
        if (LongUtils.notNullLong(tenant)) {
            var tenantId = baseOpenDispatcherConversion.tenant(tenant);
            AssertUtils.assertNotNull(tenantId, new ValueError("OpenPaySyncDTO租户不存在:" + tenant), source);
            source.setTenantId(tenantId);
        }
    }

    private void convertBelongId(OpenPaySyncDTO source) {
        //预付、到付、代收收付款 运单id
        var waybillId = source.getWaybillId();
        if (LongUtils.notNullLong(waybillId)) {
            var waybill = baseOpenDispatcherConversion.transport(waybillId);
            AssertUtils.assertNotNull(waybill, new ValueError("OpenPaySyncDTO运单不存在:" + waybillId), source);
            source.setWaybillId(waybill);
        }
        var combineId = source.getCombineId();
        if (LongUtils.notNullLong(combineId)) {
            var combine = baseOpenDispatcherConversion.combine(combineId);
            AssertUtils.assertNotNull(combine, new ValueError("OpenPaySyncDTO拼车单不存在:" + combineId), source);
            source.setCombineId(combine);
        }
        //回执付收付款 对账单id
        var billId = source.getBillId();
        if (LongUtils.notNullLong(billId)) {
            var bill = openBillCacheRepository.convert(billId);
            AssertUtils.assertNotNull(bill, new ValueError("OpenPaySyncDTO对账单不存在:" + billId), source);
            source.setBillId(bill);
        }
    }

    private void convertUser(OpenPaySyncDTO source) {
        //创建人
        var createBy = source.getCreateBy();
        if (LongUtils.notNullLong(createBy)) {
            var userId = baseOpenDispatcherConversion.user(createBy);
            AssertUtils.assertNotNull(userId, new ValueError("OpenPaySyncDTO创建者不存在:" + createBy), source);
            source.setCreateBy(userId);
        }
        //修改人
        var updateBy = source.getUpdateBy();
        if (LongUtils.notNullLong(updateBy)) {
            var userId = baseOpenDispatcherConversion.user(updateBy);
            AssertUtils.assertNotNull(userId, new ValueError("OpenPaySyncDTO修改者不存在:" + updateBy), source);
            source.setUpdateBy(userId);
        }
    }

    private void upConvert(OpenPaySyncDTO source) {
        var upStream = source.getUpStream();
        Optional.ofNullable(upStream).ifPresent(up -> {
            //租户
            var tenant = up.getTenantId();
            var tenantId = baseOpenDispatcherConversion.tenant(tenant);
            AssertUtils.assertNotNull(tenantId, new ValueError("OpenPaySyncDTO upStream 租户不存在:" + tenant), source);
            up.setTenantId(tenantId);
        });
    }

    private void downConvert(OpenPaySyncDTO source) {
        var downStream = source.getDownStream();
        Optional.ofNullable(downStream).ifPresent(down -> {
            //租户
            var tenant = down.getTenantId();
            var tenantId = baseOpenDispatcherConversion.tenant(tenant);
            AssertUtils.assertNotNull(tenantId, new ValueError("OpenPaySyncDTO downStream 租户不存在:" + tenant), source);
            down.setTenantId(tenantId);
        });
    }

    private void transportConvert(OpenPaySyncDTO source) {
        var list = source.getWaybills();
        if (!CollectionUtils.isEmpty(list)) {
            openDispatcherBillConversion.transportUpDown(list);
        }
    }
}
